//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Data;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
namespace DotNetNuke.Services.FileSystem
{
	public class FolderController
	{
		public enum StorageLocationTypes
		{
			InsecureFileSystem = 0,
			SecureFileSystem = 1,
			DatabaseSecure = 2
		}

        private static object GetFoldersByPermissionSortedCallBack(CacheItemArgs cacheItemArgs)
        {
            int portalID = (int)cacheItemArgs.ParamList[0];
            string permissions = (string)cacheItemArgs.ParamList[1];
            int userID = (int)cacheItemArgs.ParamList[2];
            return CBO.FillSortedList<string, FolderInfo>("FolderPath", DataProvider.Instance().GetFoldersByPortalAndPermissions(portalID, permissions, userID));
        }


		private static object GetFoldersSortedCallBack(CacheItemArgs cacheItemArgs)
		{
			int portalID = (int)cacheItemArgs.ParamList[0];
			return CBO.FillSortedList<string, FolderInfo>("FolderPath", DataProvider.Instance().GetFoldersByPortal(portalID));
		}

        private static void UpdateFolderVersion(int folderId)
        {
            DataProvider.Instance().UpdateFolderVersion(folderId, Guid.NewGuid());
        }


		private void UpdateParentFolder(int PortalID, string FolderPath)
		{
			if (!String.IsNullOrEmpty(FolderPath)) {
				string parentFolderPath = FolderPath.Substring(0, FolderPath.Substring(0, FolderPath.Length - 1).LastIndexOf("/") + 1);
				FolderInfo objFolder = GetFolder(PortalID, parentFolderPath, false);
				if (objFolder != null) {
					UpdateFolder(objFolder);
				}
			}
		}

        public int AddFolder(FolderInfo folder)
        {
            //Check this is not a duplicate
            FolderInfo tmpfolder = GetFolder(folder.PortalID, folder.FolderPath, true);
            if(tmpfolder != null && folder.FolderID == Null.NullInteger)
            {
                folder.FolderID = tmpfolder.FolderID;
            }
            if (folder.FolderID == Null.NullInteger)
            {
                folder.FolderPath = FileSystemUtils.FormatFolderPath(folder.FolderPath);
                folder.FolderID = DataProvider.Instance().AddFolder(folder.PortalID, folder.UniqueId, folder.VersionGuid, folder.FolderPath, folder.StorageLocation, folder.IsProtected, folder.IsCached, folder.LastUpdated, UserController.GetCurrentUserInfo().UserID);

                //Refetch folder for logging
                folder = GetFolder(folder.PortalID, folder.FolderPath, true);

                Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
                objEventLog.AddLog(folder, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, "", Log.EventLog.EventLogController.EventLogType.FOLDER_CREATED);
                UpdateParentFolder(folder.PortalID, folder.FolderPath);
            }
            else
            {
                DataProvider.Instance().UpdateFolder(folder.PortalID, folder.VersionGuid, folder.FolderID, folder.FolderPath, folder.StorageLocation, folder.IsProtected, folder.IsCached, folder.LastUpdated, UserController.GetCurrentUserInfo().UserID);
                Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
                objEventLog.AddLog("FolderPath", folder.FolderPath, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, Log.EventLog.EventLogController.EventLogType.FOLDER_UPDATED);
            }

            //Invalidate Cache
            DataCache.ClearFolderCache(folder.PortalID);

            return folder.FolderID;
        }


		public void DeleteFolder(int PortalID, string FolderPath)
		{
			DataProvider.Instance().DeleteFolder(PortalID, FileSystemUtils.FormatFolderPath(FolderPath));
			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog("FolderPath", FolderPath, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, Log.EventLog.EventLogController.EventLogType.FOLDER_DELETED);
			UpdateParentFolder(PortalID, FolderPath);
			DataCache.ClearFolderCache(PortalID);
		}
		public FolderInfo GetFolder(int PortalID, string FolderPath, bool ignoreCache)
		{
			FolderPath = FileSystemUtils.FormatFolderPath(FolderPath);
			FolderInfo folder = null;
			bool bFound = false;
			if (!ignoreCache) {
				SortedList<string, FolderInfo> dicFolders;
				dicFolders = GetFoldersSorted(PortalID);
				bFound = dicFolders.TryGetValue(FolderPath, out folder);
			}
			if (ignoreCache || !bFound)
			{
				folder = CBO.FillObject<FolderInfo>(DataProvider.Instance().GetFolder(PortalID, FolderPath));
			}
			return folder;
		}
        public FolderInfo GetFolderByUniqueID(Guid UniqueId)
        {
            FolderInfo objFolder = default(FolderInfo);
            objFolder = (FolderInfo)CBO.FillObject(DataProvider.Instance().GetFolderByUniqueID(UniqueId), typeof(FolderInfo));
            return objFolder;
        }

		public FolderInfo GetFolderInfo(int PortalID, int FolderID)
		{
			return CBO.FillObject<FolderInfo>(DataProvider.Instance().GetFolder(PortalID, FolderID));
		}

        public SortedList<string, FolderInfo> GetFoldersByPermissionsSorted(int PortalID, string Permissions, int UserID)
        {
            string cacheKey = string.Format(DataCache.FolderCacheKey, PortalID.ToString(), Permissions, UserID);
            return CBO.GetCachedObject<SortedList<string, FolderInfo>>(new CacheItemArgs(cacheKey, DataCache.FolderCacheTimeOut, DataCache.FolderCachePriority, PortalID, Permissions, UserID), GetFoldersByPermissionSortedCallBack);
        }

		public SortedList<string, FolderInfo> GetFoldersSorted(int PortalID)
		{
			string cacheKey = string.Format(DataCache.FolderCacheKey, PortalID.ToString());
			return CBO.GetCachedObject<SortedList<string, FolderInfo>>(new CacheItemArgs(cacheKey, DataCache.FolderCacheTimeOut, DataCache.FolderCachePriority, PortalID), GetFoldersSortedCallBack);
		}

		public string GetMappedDirectory(string VirtualDirectory)
		{
			string MappedDir = Convert.ToString(DataCache.GetCache("DirMap:" + VirtualDirectory));
			try {
				if (String.IsNullOrEmpty(MappedDir) && HttpContext.Current!= null)
				{
					MappedDir = FileSystemUtils.AddTrailingSlash(FileSystemUtils.MapPath(VirtualDirectory));
					DataCache.SetCache("DirMap:" + VirtualDirectory, MappedDir);
				}
			} catch (Exception exc) {
				DotNetNuke.Services.Exceptions.Exceptions.LogException(exc);
			}
			return MappedDir;
		}
		public void SetMappedDirectory(string VirtualDirectory)
		{
			try {
				string MappedDir = FileSystemUtils.AddTrailingSlash(FileSystemUtils.MapPath(VirtualDirectory));
				DataCache.SetCache("DirMap:" + VirtualDirectory, MappedDir);
			} catch (Exception exc) {
				DotNetNuke.Services.Exceptions.Exceptions.LogException(exc);
			}
		}
		public void SetMappedDirectory(string VirtualDirectory, HttpContext context)
		{
			try {
				// The logic here was updated to use the new FileSystemUtils.MapPath so that we have consistent behavior with other Overloads
				string MappedDir = FileSystemUtils.AddTrailingSlash(FileSystemUtils.MapPath(VirtualDirectory));
				DataCache.SetCache("DirMap:" + VirtualDirectory, MappedDir);
			} catch (Exception exc) {
				DotNetNuke.Services.Exceptions.Exceptions.LogException(exc);
			}
		}
		public void SetMappedDirectory(PortalInfo portalInfo, HttpContext context)
		{
			try {
				string VirtualDirectory = Common.Globals.ApplicationPath + "/" + portalInfo.HomeDirectory + "/";
				SetMappedDirectory(VirtualDirectory, context);
			} catch (Exception exc) {
				DotNetNuke.Services.Exceptions.Exceptions.LogException(exc);
			}
		}
		public void UpdateFolder(FolderInfo objFolderInfo)
		{
		    DataProvider.Instance().UpdateFolder(objFolderInfo.PortalID, objFolderInfo.VersionGuid, objFolderInfo.FolderID,
		                                         FileSystemUtils.FormatFolderPath(objFolderInfo.FolderPath),
		                                         objFolderInfo.StorageLocation, objFolderInfo.IsProtected,
		                                         objFolderInfo.IsCached, objFolderInfo.LastUpdated,
		                                         UserController.GetCurrentUserInfo().UserID);

			Services.Log.EventLog.EventLogController objEventLog = new Services.Log.EventLog.EventLogController();
			objEventLog.AddLog(objFolderInfo, PortalController.GetCurrentPortalSettings(), UserController.GetCurrentUserInfo().UserID, "", Log.EventLog.EventLogController.EventLogType.FOLDER_UPDATED);
			DataCache.ClearFolderCache(objFolderInfo.PortalID);
		}
		[Obsolete("Deprecated in DNN 5.0.  It has been replaced by GetFolderInfo(ByVal PortalID As Integer, ByVal FolderID As Integer) As FolderInfo ")]
		public ArrayList GetFolder(int PortalID, int FolderID)
		{
			ArrayList arrFolders = new ArrayList();
			FolderInfo folder = GetFolderInfo(PortalID, FolderID);
			if (folder != null) {
				arrFolders.Add(folder);
			}
			return arrFolders;
		}
		[Obsolete("Deprecated in DNN 5.0.  It has been replaced by GetFolderInfo(ByVal PortalID As Integer, ByVal FolderID As Integer, ByVal ignoreCache As Boolean) ")]
		public FolderInfo GetFolder(int PortalID, string FolderPath)
		{
			return GetFolder(PortalID, FolderPath, true);
		}
		[Obsolete("Deprecated in DNN 5.1.1.  It has been replaced by GetFolders(ByVal PortalID As Integer) As SortedList ")]
		public Dictionary<string, FolderInfo> GetFolders(int PortalID)
		{
			return new Dictionary<string, FolderInfo>(GetFoldersSorted(PortalID));
		}
		[Obsolete("Deprecated in DNN 5.0.  It has been replaced by GetFolders(ByVal PortalID As Integer) ")]
		public ArrayList GetFoldersByPortal(int PortalID)
		{
			ArrayList arrFolders = new ArrayList();
			foreach (KeyValuePair<string, FolderInfo> folderPair in GetFoldersSorted(PortalID)) {
				arrFolders.Add(folderPair.Value);
			}
			return arrFolders;
		}
        [Obsolete("Deprecated in DotNetNuke 5.5. This function has been replaced by AddFolder(ByVal folder As FolderInfo)")]
        public int AddFolder(int PortalID, string FolderPath)
        {
            FolderInfo objFolder = new FolderInfo();

            objFolder.UniqueId = Guid.NewGuid();
            objFolder.VersionGuid = Guid.NewGuid();
            objFolder.PortalID = PortalID;
            objFolder.FolderPath = FolderPath;
            objFolder.StorageLocation = (int)StorageLocationTypes.InsecureFileSystem;
            objFolder.IsProtected = false;
            objFolder.IsCached = false;

            return AddFolder(objFolder);
        }

        [Obsolete("Deprecated in DotNetNuke 5.5. This function has been replaced by AddFolder(ByVal folder As FolderInfo)")]
        public int AddFolder(int PortalID, string FolderPath, int StorageLocation, bool IsProtected, bool IsCached)
        {
            FolderInfo objFolder = new FolderInfo();

            objFolder.UniqueId = Guid.NewGuid();
            objFolder.VersionGuid = Guid.NewGuid();
            objFolder.PortalID = PortalID;
            objFolder.FolderPath = FolderPath;
            objFolder.StorageLocation = StorageLocation;
            objFolder.IsProtected = IsProtected;
            objFolder.IsCached = IsCached;

            return AddFolder(objFolder);
        }

        [Obsolete("Deprecated in DotNetNuke 5.5. This function has been replaced by AddFolder(ByVal folder As FolderInfo)")]

        public int AddFolder(int PortalID, string FolderPath, int StorageLocation, bool IsProtected, bool IsCached, System.DateTime LastUpdated)
        {
            FolderPath = FileSystemUtils.FormatFolderPath(FolderPath);
            FolderInfo folder = GetFolder(PortalID, FolderPath, true);

            folder.StorageLocation = StorageLocation;
            folder.IsProtected = IsProtected;
            folder.IsCached = IsCached;
            folder.LastUpdated = Null.NullDate;

            DataCache.ClearFolderCache(PortalID);

            return AddFolder(folder);
        }

	}
}
